import pandas as pd
from pypinyin import lazy_pinyin
import re
from collections import Counter
import json
import platform


def csv_gbk_to_utf(csv_gbk_path, csv_utf_path):
    """对于通过sav得到的csv，需要处理编码
    1. 将SPSS系统切换为gbk编码
    2. 打开shidaoai.sav数据，导出为shidaoai.csv。此时shidaoai.csv为gbk编码
    3. 使用pandas以gbk编码打开shidaoai.csv，然后以utf-8编码另存为shidaoai_utf.csv
    4. 此时的shidaoai_utf.csv是utf-8编码，可以被使用
    Args:
        sav_csv_path (str): 通过sav文件转化为csv文件的路径
    """
    df_csv = pd.read_csv(csv_gbk_path, encoding='gbk')
    df_csv.to_csv(csv_utf_path, encoding='utf-8')


def convert_excel_to_csv(excel_path, csv_path, sheet_name, encoding='utf-8'):
    """Convert xlsx to csv.
    Args:
        excel_path (str): Path of the features excel file.
        sheet_name (str): Sheet name of the features excel file.
        csv_path (str): Path of the features csv file.
    """
    df_features = pd.read_excel(excel_path, sheet_name=sheet_name)
    df_features.to_csv(csv_path, index=False, encoding=encoding)


def _features_string_cutter(string):
    """对于features.csv文件，进行字符串切分，并转换为标准格式
    Args:
        string (str): 待转换的字符串
    Returns:
        str: 转换后的字符串
    """
    # 仅保留小写字母
    # string_new = ''.join(re.findall('[a-z]', string.split('^')[0].lower()))
    string_new = ''.join(re.findall('[a-z ]', string.split('^')[0].lower())).strip()

    subkey = 'features'
    otherkey = 'shidaoai'
    # ! <<< Modify name record json.
    # name_record_json_path = 'G:/_project/shidaoai_new_project/data/_out/tab/name_record.json'
    # with open(name_record_json_path, 'r', encoding='utf-8') as f:
    #     name_record = json.load(f)
    # if string_new not in name_record.keys():
    #     name_record[string_new] = {}
    # if subkey not in name_record[string_new].keys():
    #     name_record[string_new][subkey] = [string]
    # # elif string not in name_record[string_new]['features']:
    # else:
    #     name_record[string_new][subkey].append(string)
    # # name_record = json.dumps(name_record, indent=4)
    # with open(name_record_json_path, 'w', encoding='utf-8') as f:
    #     json.dump(name_record, f, ensure_ascii=False)
    # ! >>>

    # ! <<< Check the json and convert string.
    if platform.system() == 'Windows':
        name_record_json_path = 'G:/_project/shidaoai_new_project/data/_out/tab/name_record.json'
    else:
        name_record_json_path = '/home/yusongli/_project/shidaoai/data/_out/tab/name_record.json'
    with open(name_record_json_path, 'r', encoding='utf-8') as f:
        name_record = json.load(f)
    if string_new not in name_record.keys():
        print(f'{string}: the converted {string_new} not in json.')
        return string
    if subkey not in name_record[string_new].keys():
        print(f'{string}: missing {subkey} key.')
        return string
    if otherkey not in name_record[string_new].keys():
        print(f'{string}: missing {otherkey} key.')
        return string
    if len(name_record[string_new]['features']) != 2 or name_record[string_new]['features'][0] != name_record[string_new]['features'][1] or len(name_record[string_new]['shidaoai']) != 1:
        print(f'{string}: multiple features names or multiple shidaoai names.')
        return string
    # ! >>>

    return string_new


def _shidaoai_pinyin_converter(string):
    string_new = ' '.join(lazy_pinyin(string.split('*')[0])).strip()

    subkey = 'shidaoai'
    otherkey = 'features'
    # ! <<< Modify name record json.
    # name_record_json_path = 'G:/_project/shidaoai_new_project/data/_out/tab/name_record.json'
    # with open(name_record_json_path, 'r', encoding='utf-8') as f:
    #     name_record = json.load(f)
    # if string_new not in name_record.keys():
    #     name_record[string_new] = {}
    # if subkey not in name_record[string_new].keys():
    #     name_record[string_new][subkey] = [string]
    # # elif string not in name_record[string_new]['features']:
    # else:
    #     name_record[string_new][subkey].append(string)
    # # name_record = json.dumps(name_record, indent=4)
    # with open(name_record_json_path, 'w', encoding='utf-8') as f:
    #     json.dump(name_record, f, ensure_ascii=False)
    # ! >>>

    # ! <<< Check the json and convert string.
    if platform.system() == 'Windows':
        name_record_json_path = 'G:/_project/shidaoai_new_project/data/_out/tab/name_record.json'
    else:
        name_record_json_path = '/home/yusongli/_project/shidaoai/data/_out/tab/name_record.json'
    with open(name_record_json_path, 'r', encoding='utf-8') as f:
        name_record = json.load(f)
    if string_new not in name_record.keys():
        print(f'{string}: the converted {string_new} not in json.')
        return string
    if subkey not in name_record[string_new].keys():
        print(f'{string}: missing {subkey} key.')
        return string
    if otherkey not in name_record[string_new].keys():
        print(f'{string}: missing {otherkey} key.')
        return string
    if len(name_record[string_new]['features']) != 2 or name_record[string_new]['features'][0] != name_record[string_new]['features'][1] or len(name_record[string_new]['shidaoai']) != 1:
        print(f'{string}: multiple features names or multiple shidaoai names.')
        return string
    # ! >>>

    return string_new


def _shidaoai_gtvt_label_merger(string):
    try:
        label = int(string)
        if label == 0:
            return '0'
        if label in {1, 2}:
            return '1'
        if label == 3:
            return '2'
        if label == 4:
            return '3'
        if label in {5, 6}:
            return '4'
    except:
        return string
    return string


def column_apply(df, column, func):
    """Apply a function to a column of a dataframe.
    Args:
        df (pandas.DataFrame): data frame.
        column (str): column name.
        func (function): lambda function.
    """
    # 读取features.csv
    # df = pd.read_csv('data/features.csv')
    # 提取出所有'ROI '列的值为'GTV-T1'的行
    # roi_class = ['GTV-T1']
    # df = df.loc[df['ROI '] == roi_class]

    # 对'Image'列进行字符串裁剪
    df[column] = df[column].apply(lambda x: func(x))
    # df = df.sort_values(by='Image', ascending=True)
    # 把'Image'列名修改为'Person'
    # df.rename(columns={'Image': 'Person'}, inplace=True)
    return df


# def process_shidaoai():
#     """对shidaoai_utf.csv进行数据预处理
#     """
#     df = pd.read_csv('data/shidaoai_utf.csv')
#     # 把患者姓名换成拼音
#     df['患者姓名'] = df['患者姓名'].apply(lambda x: _shidaoai_pinyin_converter(x))
#     df = df.sort_values(by='患者姓名', ascending=True)
#     # 把'患者姓名'列名修改为'Person'
#     df.rename(columns={'患者姓名': 'Person'}, inplace=True)
#     return df


def get_intersect(roi_class='GTV-T1'):
    """按'Person'列取两表的交集。这里的两个表是指完全处理好的表。
    """
    df_features = process_features(roi_class)
    df_shidaoai = process_shidaoai()
    intersected = pd.merge(df_features, df_shidaoai, on=['Person'])
    intersected.to_csv('data/intersected_' + roi_class + '.csv', index=False)


def kps(df):
    # 计算每个值的数量
    counter = Counter(df['KPS评分分级'])
    # 对于计数器进行排序
    counter_sort_list = sorted(counter.items(), key=lambda k: k[0])
    counter_sort_list_portion = list(map(lambda x: x[1] / df.shape[0], counter_sort_list))
    print(counter_sort_list)
    print(counter_sort_list_portion)


def output_gbk(df):
    df.to_csv('data/intersected_gbk.csv', encoding='gbk', index=False)


def check(df):
    print(df.shape)
